<!-- ---------------------------
    ## 人事管理 - 日历
--------------------------- -->
<template>
    <div class="date-picker" @click.stop>
        <div class="topbar clearfix">
            <span class="current">
                <span class="year" @click="panelType = 'year'">{{ tmpYear }}年</span>
                <span class="month" @click="panelType = 'month'">{{ changeTmpMonth }}</span>
            </span>
            <span class="float-right">
                <button @click="backToToday">回今天</button>
                <i class="icon iconfont icon-arrow-up iconarrowdown" @click="left"></i>
                <i class="icon iconfont icon-arrow-down iconarrowdown" @click="right"></i>
            </span>
        </div>
        <div v-self-loading="todoListLoading">
            <!-- 年面板 -->
            <div class="type-year" v-show="panelType === 'year'">
                <ul class="year-list">
                    <li v-for="(item, index) in yearList" :key="index" @click="selectYear(item)">
                        <span :class="{selected: item === tmpYear}">{{ item }}</span>
                    </li>
                </ul>
            </div>
            <!-- 月面板 -->
            <div class="type-year" v-show="panelType === 'month'">
                <ul class="year-list">
                    <li v-for="(item, index) in monthList" :key="index" @click="selectMonth(item)">
                        <span :class="{selected: item.value === tmpMonth}">{{ item.label }}</span>
                    </li>
                </ul>
            </div>
            <!-- 日期面板 -->
            <div class="date-group" v-show="panelType === 'date'">
                <div class="date-group-header">
                    <span
                            class="weekday"
                            v-for="(item, index) in weekList"
                            :key="index"
                    >{{ item.label }}</span>
                </div>
                <ul class="date-list">
                    <li
                            v-for="(item, index) in dateList"
                            :class="{ 'preMonth': item.previousMonth,
                    'nextMonth': item.nextMonth,
                    'selected': date === item.value && month === tmpMonth && item.currentMonth, 
                    'invalid': validateDate(item),
                    'has-item': item.hasItem
                     }"
                            :key="index"
                            @click="selectDate(item)"
                    >
                        <i>{{ item.value }}</i>
                        <em
                                class="date-label"
                                v-if="!!item.label"
                                :class="{'high-light': item.label === '班'}"
                        >{{ item.label }}</em>
                    </li>
                </ul>
            </div>
        </div>
    </div>
</template>

<script>
function dateFormat(date, fmt = 'yyyy-MM-dd') {
    if (!date) return "";
    try {
        if (typeof date === "number" || typeof date === "string") {
            date = new Date(date)
        }
        let dateList = {
            "M+": date.getMonth() + 1,
            "d+": date.getDate(),
            "H+": date.getHours(),
            "m+": date.getMinutes(),
            "s+": date.getSeconds(),
            "q+": Math.floor((date.getMonth() + 3) / 3),
            "S+": date.getMilliseconds()
        };
        if (/(y+)/i.test(fmt)) {
            fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
        }
        for (var k in dateList) {
            if (new RegExp("(" + k + ")").test(fmt)) {
                fmt = fmt.replace(RegExp.$1, RegExp.$1.length == 1 ? dateList[k] : ("00" + dateList[k]).substr(("" + dateList[k]).length));
            }
        }
    } catch (error) {
        fmt = ""
    }
    return fmt;
}


    const format = "yyyy-MM-dd";

    export default {
        props: {
            // options: {
            //     type: Object,
            //     required: false,
            //     default: () => {
            //         return {};
            //     }
            // }
        },
        data() {
            return {
                date: new Date().getDate(), // 当前日期
                month: new Date().getMonth(), // 当前月份

                tmpMonth: new Date().getMonth(), // 当前显示月份，可修改
                tmpYear: new Date().getFullYear(), // 当前显示年份，可修改
                weekList: [
                    {label: "日", value: 0},
                    {label: "一", value: 1},
                    {label: "二", value: 2},
                    {label: "三", value: 3},
                    {label: "四", value: 4},
                    {label: "五", value: 5},
                    {label: "六", value: 6},
                ], // 周
                monthList: [
                    {label: "1月", value: 0},
                    {label: "2月", value: 1},
                    {label: "3月", value: 2},
                    {label: "4月", value: 3},
                    {label: "5月", value: 4},
                    {label: "6月", value: 5},
                    {label: "7月", value: 6},
                    {label: "8月", value: 7},
                    {label: "9月", value: 8},
                    {label: "10月", value: 9},
                    {label: "11月", value: 10},
                    {label: "12月", value: 11},
                ], // 月
                panelType: "date", // 面板状态

                selectedDateTime: 0,

                options: {},

                todoListLoading: "loading",
            };
        },
        computed: {
            dateList() {
                //获取当月的天数
                let currentMonthLength = new Date(
                        this.tmpYear,
                        this.tmpMonth + 1,
                        0
                ).getDate();
                //先将当月的日期塞入dateList
                let dateList = Array.from(
                        {length: currentMonthLength},
                        (val, index) => {
                            return {
                                currentMonth: true,
                                value: index + 1,
                                // 是补班还是休息
                                label: "",
                                // 有没有代办事项
                                hasItem: false,
                                todoList: [],
                            };
                        }
                );
                // 获取当月1号的星期是为了确定在1号前需要插多少天
                let startDay = new Date(this.tmpYear, this.tmpMonth, 1).getDay();
                // 确认上个月一共多少天
                let previousMongthLength = new Date(
                        this.tmpYear,
                        this.tmpMonth,
                        0
                ).getDate();
                // 在1号前插入上个月日期
                for (let i = 0, len = startDay; i < len; i++) {
                    dateList = [
                        {
                            previousMonth: true,
                            value: previousMongthLength - i,
                            label: "",
                            hasItem: false,
                            todoList: [],
                        },
                    ].concat(dateList);
                }
                // 补全剩余位置
                for (let i = 1, item = 1; i < 15; i++, item++) {
                    dateList[dateList.length] = {
                        nextMonth: true,
                        value: i,
                        label: "",
                        hasItem: false,
                        todoList: [],
                    };
                }
                return dateList;
            },
            changeTmpMonth() {
                return this.monthList[this.tmpMonth].label;
            },
            yearList() {
                return Array.from(
                        {length: 12},
                        (value, index) => this.tmpYear + index
                );
            },
        },
        mounted() {
            // 默认选中今天
            let temp = new Date(this.tmpYear, this.tmpMonth, this.date);
            this.selectedDateTime = temp.getTime();
        },
        methods: {
            /**
             * 上个月
             */
            left() {
                if (this.panelType === "year") this.tmpYear--;
                else {
                    if (this.tmpMonth === 0) {
                        this.tmpYear--;
                        this.tmpMonth = 11;
                    } else this.tmpMonth--;
                }
            },

            /**
             * 下个月
             */
            right() {
                if (this.panelType === "year") this.tmpYear++;
                else {
                    if (this.tmpMonth === 11) {
                        this.tmpYear++;
                        this.tmpMonth = 0;
                    } else this.tmpMonth++;
                }
            },

            /**
             * 计算是否选中某天
             */
            validateDate(item) {
                return (
                        new Date(this.tmpYear, this.tmpMonth, item.value).getTime() ===
                        this.selectedDateTime && item.currentMonth
                );
            },

            /**
             * 选中某天事件
             */
            selectDate(item) {
                if (item.previousMonth) this.tmpMonth--;
                if (item.nextMonth) this.tmpMonth++;
                let selectDay = new Date(this.tmpYear, this.tmpMonth, item.value);
                this.selectedDateTime = selectDay.getTime();
                let dateData = {
                    date: selectDay,
                    todoList: item.todoList,
                };
                this.$emit("on-select", dateData);
            },

            /**
             * 选中某年事件
             */
            selectYear(item) {
                this.tmpYear = item;
                this.panelType = "month";
            },

            /**
             * 选中某月事件
             */
            selectMonth(item) {
                this.tmpMonth = item.value;
                this.panelType = "date";
            },

            /**
             * 回今天
             */
            backToToday() {
                this.tmpYear = new Date().getFullYear();
                this.tmpMonth = new Date().getMonth();

                let temp = new Date(this.tmpYear, this.tmpMonth, this.date);
                let dateData = {
                    date: temp,
                    todoList: [],
                };
                this.$emit("on-select", dateData);
                this.selectedDateTime = temp.getTime();
            },

            setByOptions() {
                const setOneDay = (date, data) => {
                    let list = this.dateList.filter(
                            (item) => !item.previousMonth && !item.nextMonth
                    );
                    let len = list.length;
                    for (let i = 0; i < len; i += 1) {
                        if (list[i].value === date) {
                            list[i].label = data.label;
                            list[i].hasItem = data.hasItem;
                            list[i].todoList = data.todoList;
                            break;
                        }
                    }
                };
                for (const key in this.options) {
                    if (Object.prototype.hasOwnProperty.call( this.options,key)) {
                        let dateNum = parseInt(key);
                        let year = parseInt(dateNum / 10000);
                        let month = parseInt((dateNum % 10000) / 100) - 1;
                        let date = dateNum % 100;
                        if (year === this.tmpYear && month === this.tmpMonth) {
                            setOneDay(date, this.options[key]);
                        }
                    }
                }
                this.$forceUpdate();
            },

            /**
             * 获取本月的待办事项
             */
            getTodoList() {
                this.todoListLoading = "loading";
                queryMonthTodo(
                        dateFormat(new Date(this.tmpYear, this.tmpMonth), "yyyy-MM")
                ).then(({data}) => {
                    this.options = {};
                    data.forEach((todoItem) => {
                        let key = todoItem.time.split("-").join("");
                        if (!!this.options[key]) {
                            this.options[key].todoList.push(todoItem);
                        } else {
                            this.options[key] = {
                                hasItem: true,
                                label: "",
                                todoList: [todoItem],
                            };
                        }
                    });
                    this.todoListLoading = "suc";
                    this.setByOptions();
                }).catch(() => {
                    this.todoListLoading = "failed";
                });
            },
        },
    };
</script>
<style lang="scss">
$font-color: #262626 !default; // 默认字体颜色
$blue: #1473E6 !default; // 主题配色
$red: #f55959; // 错误配色
$green: #1cc336;

    .date-picker {
        $width: 340px;
        $date-height: 39px;
        line-height: 1;
        font-size: 14px;
        text-align: left;
        width: $width;
        text-align: center;
        color: $font-color;
        font-weight: normal;
        background-color: #fff;
        user-select: none;

        .topbar {
            padding: 15px 16px 10px;
            text-align: left;
            line-height: 21px;

            .current {
                font-size: 18px;
                letter-spacing: 1px;
                font-weight: bold;
            }

            button {
                height: 21px;
                margin-right: 34px;
                border: none;
                line-height: 21px;
                outline: none;
                color: #8690a7;
                background-color: transparent;
            }

            .icon {
                color: #8690a7;
                font-size: 14px;
                cursor: pointer;

                &:hover {
                    color: $blue;
                }
            }

            .icon-arrow-up {
                transform: rotate(180deg);
            }

            .icon-arrow-down {
                margin-left: 36px;
            }

            span {
                cursor: pointer;
            }
        }

        .year-list {
            height: 200px;
            width: $width;
        }

        .year-list .selected {
            background: #2d8cf0;
            border-radius: 4px;
            color: #fff;
        }

        .year-list li {
            display: inline-block;
            width: $width / 3;
            height: 50px;
            line-height: 50px;
            border-radius: 10px;
            cursor: pointer;
        }

        .year-list span {
            display: inline-block;
            line-height: 16px;
            padding: 8px;
        }

        .year-list span:hover {
            background: #e1f0fe;
        }

        .weekday {
            display: inline-block;
            width: $width / 7;
            padding: 10px 0;
            line-height: 19px;
            text-align: center;
        }

        .date-panel {
            width: $width;
            box-shadow: 0 0 8px #ccc;
            background: #fff;
        }

        ul {
            list-style: none;
            padding: 0;
            margin: 0;
        }

        .date-list {
            width: $width;
            text-align: left;
            height: $date-height * 6;
            overflow: hidden;

            li {
                position: relative;
                top: 0;
                left: 0;
                display: inline-block;
                width: $width / 7;
                height: $date-height;
                padding-top: 10px;
                padding-bottom: 10px;
                line-height: 19px;
                text-align: center;
                cursor: pointer;
                color: #000;
                border-radius: 4px;

                i {
                    position: relative;
                    z-index: 3;
                }

                /* 有待办事项的样式 */
                &.has-item {
                    &::after {
                        content: "";
                        display: block;
                        width: 4px;
                        height: 4px;
                        background-color: #8690a7;
                        border-radius: 2px;
                        opacity: 0.5;
                        position: absolute;
                        z-index: 4;
                        bottom: 6px;
                        left: 50%;
                        transform: translateX(-2px);
                    }
                }

                /* date label */
                em {
                    font-style: normal;
                    position: absolute;
                    z-index: 5;
                    top: 0;
                    left: 0;
                    font-size: 12px;
                    width: 20px;
                    height: 20px;
                    border: 1px solid #1d94f7;
                    line-height: 20px - 1px - 1px;
                    text-align: center;
                    color: #1d94f7;
                    border-radius: 9px;
                    transform: scale(0.75);

                    &.high-light {
                        border-color: $red;
                        color: $red;
                    }
                }

                &:hover {
                    color: $font-color;

                    &::before {
                        content: "";
                        position: absolute;
                        top: ($date-height - 34px) / 2;
                        left: (($width / 7) - 34px) / 2;
                        display: block;
                        width: 34px;
                        height: 34px;
                        border-radius: 17px;
                        background-color: #e1f0fe;
                    }
                }

                /* 今天的样式 */
                &.selected {
                    color: #1d94f7;

                    &::before {
                        content: "";
                        position: absolute;
                        z-index: 2;
                        top: ($date-height - 34px) / 2;
                        left: (($width / 7) - 34px) / 2;
                        display: block;
                        width: 34px;
                        height: 34px;
                        color: #fff;
                        line-height: 34px - 1px - 1px;
                        text-align: center;
                        border: 1px solid #1d94f7;
                        border-radius: 17px;
                    }

                    &.invalid::before {
                        background-color: #1d94f7;
                        content: "今";
                    }
                }

                /* 选中日期的样式 */
                &.invalid {
                    color: #fff;
                    background: transparent;

                    &::before {
                        content: "";
                        position: absolute;
                        top: ($date-height - 34px) / 2;
                        left: (($width / 7) - 34px) / 2;
                        display: block;
                        width: 34px;
                        height: 34px;
                        border-radius: 17px;
                        background-color: #1d94f7;
                    }
                }

                &.selected.invalid::before {
                    z-index: 4;
                    background: #1d94f7;
                    content: "今";
                }
            }
        }

        .date-list .preMonth,
        .date-list .nextMonth {
            color: #c5c8ce;
        }
    }
</style>
